xend: Receive error message of migration from destination server
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 15 Sep 2009 08:20:47 +0000 (09:20 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 15 Sep 2009 08:20:47 +0000 (09:20 +0100)
The following error message was shown by xm migrate command.
In fact, I caused the command error by intention.  I prepared a
destination server where free memory was insufficient, and then
I tried to migrate a VM to the destination server.  As I had
expected, the command error occurred.  However the error message
was different from my expectation.  I would like to show an error
message from the destination server if an error occurred on the
destination server.

# xm migrate --live vm3 bx339
Error: (107, 'Transport endpoint is not connected')
Usage: xm migrate <Domain> <Host>

Migrate a domain to another machine.

Options:

-h, --help           Print this help.
-l, --live           Use live migration.
-p=3Dportnum, --port=3Dportnum
                     Use specified port for migration.
-n=3Dnodenum, --node=3Dnodenum
                     Use specified NUMA node on target.
-s, --ssl            Use ssl connection for migration.

If a destination server sends an error message, this patch shows=20
the error message.  For example, the following error message is=20
shown if free memory of the destination server is insufficient.

# xm migrate --live vm3 bx339
Error: I need 262144 KiB, but dom0_min_mem is 716800 and shrinking
to=20
716800 KiB would leave only 50368 KiB free. (from bx339)
Usage: xm migrate <Domain> <Host>

Migrate a domain to another machine.

Options:

-h, --help           Print this help.
-l, --live           Use live migration.
-p=3Dportnum, --port=3Dportnum
                     Use specified port for migration.
-n=3Dnodenum, --node=3Dnodenum
                     Use specified NUMA node on target.
-s, --ssl            Use ssl connection for migration.

Signed-off-by: Masaki Kanno <kanno.masaki@jp.fujitsu.com>
tools/python/xen/xend/XendDomain.py

index a8ac3174222e68dfa32b43d19f0caf484faabc63..594d49298a61289901ba1a9dfd0912b5559b1601 100644 (file)
@@ -28,6 +28,7 @@ import shutil
 import socket
 import tempfile
 import threading
+import re
 
 import xen.lowlevel.xc
 
@@ -1350,10 +1351,40 @@ class XendDomain:
                              args=(sock, p2cread)).start()
 
             try:
-                XendCheckpoint.save(p2cwrite, dominfo, True, live, dst,
-                                    node=node)
+                try:
+                    XendCheckpoint.save(p2cwrite, dominfo, True, live, dst,
+                                        node=node)
+                except Exception, ex:
+                    m_dsterr = None
+                    try:
+                        sock.settimeout(3.0)
+                        dsterr = sock.recv(1024)
+                        sock.settimeout(None)
+                        if dsterr:
+                            # See send_error@relocate.py. If an error occurred
+                            # in a destination side, an error message with the
+                            # following form is returned from the destination
+                            # side.
+                            m_dsterr = \
+                                re.match(r"^\(err\s\(type\s(.+)\)\s\(value\s'(.+)'\)\)", dsterr)
+                    except:
+                        # Probably socket.timeout exception occurred.
+                        # Ignore the exception because it has nothing to do with
+                        # an exception of XendCheckpoint.save.
+                        pass
+
+                    if m_dsterr:
+                        raise XendError("%s (from %s)" % (m_dsterr.group(2), dst))
+                    raise
             finally:
-                sock.shutdown(2)
+                try:
+                    sock.shutdown(2)
+                except:
+                    # Probably the socket is already disconnected by sock.close
+                    # in the destination side.
+                    # Ignore the exception because it has nothing to do with
+                    # an exception of XendCheckpoint.save.
+                    pass
                 sock.close()
 
             os.close(p2cread)
@@ -1376,10 +1407,40 @@ class XendDomain:
                 raise XendError("can't connect: %s" % err)
 
             try:
-                XendCheckpoint.save(sock.fileno(), dominfo, True, live,
-                                    dst, node=node)
+                try:
+                    XendCheckpoint.save(sock.fileno(), dominfo, True, live,
+                                        dst, node=node)
+                except Exception, ex:
+                    m_dsterr = None
+                    try:
+                        sock.settimeout(3.0)
+                        dsterr = sock.recv(1024)
+                        sock.settimeout(None)
+                        if dsterr:
+                            # See send_error@relocate.py. If an error occurred
+                            # in a destination side, an error message with the
+                            # following form is returned from the destination
+                            # side.
+                            m_dsterr = \
+                                re.match(r"^\(err\s\(type\s(.+)\)\s\(value\s'(.+)'\)\)", dsterr)
+                    except:
+                        # Probably socket.timeout exception occurred.
+                        # Ignore the exception because it has nothing to do with
+                        # an exception of XendCheckpoint.save.
+                        pass
+
+                    if m_dsterr:
+                        raise XendError("%s (from %s)" % (m_dsterr.group(2), dst))
+                    raise
             finally:
-                sock.shutdown(2)
+                try:
+                    sock.shutdown(2)
+                except:
+                    # Probably the socket is already disconnected by sock.close
+                    # in the destination side.
+                    # Ignore the exception because it has nothing to do with
+                    # an exception of XendCheckpoint.save.
+                    pass
                 sock.close()
 
     def domain_save(self, domid, dst, checkpoint=False):